package com.capinfo.service.impl;

import com.capinfo.base.BaseMapper;
import com.capinfo.base.CurrentUser;
import com.capinfo.base.impl.BaseServiceImpl;
import com.capinfo.entity.CapApprovalSuggestion;
import com.capinfo.entity.CapPreApproval;
import com.capinfo.entity.CapService;
import com.capinfo.entity.SysRoleUser;
import com.capinfo.mapper.CapPreApprovalMapper;
import com.capinfo.service.CapPreApprovalService;
import com.capinfo.service.CapServiceService;
import com.capinfo.service.RoleUserService;
import com.capinfo.util.BeanUtil;
import com.capinfo.util.CommonUtil;
import com.capinfo.utils.ApprovalConstant;
import com.capinfo.utils.ApprovalFlowEnum;
import com.capinfo.utils.RedisUtils;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author: sunbenjin
 * @date: 2020/2/27
 **/
@Service
public class CapPreApprovalServiceImpl extends BaseServiceImpl<CapPreApproval, String> implements CapPreApprovalService {

    @Autowired
    private CapPreApprovalMapper capPreApprovalMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private CapServiceService capServiceService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RoleUserService roleUserService;

    @Override
    public List<CapPreApproval> selectListByPage(CapPreApproval record) {
        return capPreApprovalMapper.selectListByPage(record);
    }

    @Override
    public int insert(CapPreApproval capPreApproval) {
        capPreApproval = super.addValue(capPreApproval,false);
        return capPreApprovalMapper.insert(capPreApproval);
    }

    @Override
    public CapPreApproval selectByPrimaryKey(Object o) {
        return capPreApprovalMapper.selectByPrimaryKey(o);
    }


    @Override
    public BaseMapper<CapPreApproval, String> getMappser() {
        return capPreApprovalMapper;
    }



    @Override
    public Map<String,String> setSerialNo(String orderName, int type) {
        return capPreApprovalMapper.setSerialNo(orderName,type);
    }

    @Override
    public void setApprovalSuggestionToRedis(CapPreApproval capPreApproval) {
        if(StringUtils.isNotEmpty(capPreApproval.getApprovalSuggestion())){
            String key = capPreApproval.getId();
            String suggestion = capPreApproval.getApprovalSuggestion();
            List<Object> suggestions =redisUtils.lRange(key,0,-1);
            if(CollectionUtils.isEmpty(suggestions)){
                CapApprovalSuggestion capApprovalSuggestion = new CapApprovalSuggestion(suggestion,new Date());

                redisUtils.lPush(key,capApprovalSuggestion);
            }else {
                Object o = (Object) suggestions;
                List<CapApprovalSuggestion> list = (List<CapApprovalSuggestion>)o;
                list.add(new CapApprovalSuggestion(suggestion,new Date()));
                redisUtils.remove(key);
                for(CapApprovalSuggestion approvalSuggestion:list){
                    redisUtils.lPush(key,approvalSuggestion);
                }

            }
        }
    }

    @Override
    public int save(CapPreApproval capPreApproval) {
        String userId = CommonUtil.getUser().getId();
        Map<String,Object> map = new HashMap<>();
        Integer saveActionFlag = capPreApproval.getSaveActionFlag();
        String procInsId = "";
        if(StringUtils.isEmpty(capPreApproval.getId())){
            String id = (UUID.randomUUID()+"").replaceAll("-","");
            capPreApproval.setId(id);

            capPreApproval.setCreateDate(new Date());
            capPreApproval.setCreateBy(userId);
            capPreApproval.setDelFlag("0");
            if(saveActionFlag!=null){
                if(saveActionFlag==0){
                    startProcess(capPreApproval,procInsId, map);
                }
            }
            if(StringUtils.isEmpty(capPreApproval.getApprovalNumber())){
                Map<String,String> serialNo = this.setSerialNo("YS",8);
                capPreApproval.setApprovalNumber(serialNo.get("newOrderNo").toString());
            }
            this.insert(capPreApproval);
        }else{

            switch (saveActionFlag){
                case 0:
                    if(StringUtils.isEmpty(capPreApproval.getApprovalNumber())){
                        Map<String,String> serialNo = this.setSerialNo("YS",8);
                        capPreApproval.setApprovalNumber(serialNo.get("newOrderNo").toString());
                    }
                    CapPreApproval restartApproval = this.selectByPrimaryKey(capPreApproval.getId());
                    if(restartApproval!=null){
                        procInsId = restartApproval.getProcInsId();

                    }

                    startProcess(capPreApproval,procInsId,map);
                    BeanUtil.copyNotNullBean(capPreApproval,restartApproval);
                    this.updateByPrimaryKeySelective(restartApproval);
                    break;
                case 1:
                    if(StringUtils.isNotEmpty(capPreApproval.getApprovalSuggestion())){
                        this.setApprovalSuggestionToRedis(capPreApproval);
                    }
                    CapPreApproval oldReFill = this.selectByPrimaryKey(capPreApproval.getId());
                    procInsId = oldReFill.getProcInsId();
                    capPreApproval.setTaskStatus(ApprovalConstant.TASKSTATUS[0]);
                    reFillProcess(capPreApproval,procInsId,map);
                    BeanUtil.copyNotNullBean(capPreApproval,oldReFill);
                    this.updateByPrimaryKeySelective(oldReFill);
                    break;
                case 2:
                    if(StringUtils.isNotEmpty(capPreApproval.getApprovalSuggestion())){
                        this.setApprovalSuggestionToRedis(capPreApproval);
                    }
                    CapPreApproval oldFinish = this.selectByPrimaryKey(capPreApproval.getId());
                    procInsId = oldFinish.getProcInsId();
                    finishProcess(capPreApproval,procInsId,map);
                    BeanUtil.copyNotNullBean(capPreApproval,oldFinish);
                    oldFinish.setApprovalPerson(userId);
                    this.updateByPrimaryKeySelective(oldFinish);
                    break;
                case 3:
                    CapPreApproval oldForce = this.selectByPrimaryKey(capPreApproval.getId());
                    procInsId = oldForce.getProcInsId();
                    forceEndProcess(capPreApproval,procInsId,map);
                    BeanUtil.copyNotNullBean(capPreApproval,oldForce);
                    this.updateByPrimaryKeySelective(oldForce);
                    break;
                default:
                    break;
            }


        }
        return 0;
    }

    @Override
    public boolean isApproverRole(CurrentUser user) {
        SysRoleUser sysRoleUser =  new SysRoleUser();
        sysRoleUser.setUserId(user.getId());
        sysRoleUser.setRoleId(ApprovalConstant.APPROVAL_ROLE_ID);
        int count = roleUserService.selectCountByCondition(sysRoleUser);
        return count>0;
    }

    //取消预审
    private void forceEndProcess(CapPreApproval capPreApproval,String procInsId, Map<String, Object> map) {
        capPreApproval.setApprovalStatus(ApprovalFlowEnum.getNowNodeStatus("取消预审").getStatus());
        capPreApproval.setTaskStatus(ApprovalConstant.TASKSTATUS[1]);
        capPreApproval.setApprovalPerson(capPreApproval.getCreateBy());
        Task task =taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
        if(task!=null){
            taskService.addComment(task.getId(),procInsId,"forceEnd[取消预审]");
            map.put("pass","1");
            taskService.complete(task.getId(),map);
            taskService.deleteTask(task.getId());
            if(StringUtils.equals(task.getName(),"修改")){
                 task =  taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
                taskService.complete(task.getId(),map);
                taskService.deleteTask(task.getId());
            }


        }
    }


    //预审完成
    private void finishProcess(CapPreApproval capPreApproval,String procInsId,Map<String, Object> map) {
        CapPreApproval old = this.selectByPrimaryKey(capPreApproval.getId());

        capPreApproval.setApprovalStatus(ApprovalFlowEnum.getNowNodeStatus("预审完成").getStatus());
        capPreApproval.setTaskStatus(ApprovalConstant.TASKSTATUS[1]);

        Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
        if(task!=null){
            taskService.addComment(task.getId(),procInsId,"finish[预审完成]");
            map.put("pass","1");
            taskService.complete(task.getId(),map);
        }
    }

    //返回重新填报材料
    private void reFillProcess(CapPreApproval capPreApproval,String procInsId, Map<String, Object> map) {

        capPreApproval.setApprovalStatus(ApprovalFlowEnum.getNowNodeStatus("返回重新填报材料").getStatus());
        capPreApproval.setTaskStatus(ApprovalConstant.TASKSTATUS[0]);
        Task task =taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
        if(task!=null){
            taskService.addComment(task.getId(),procInsId,"reFill[返回重新填报材料]");
            map.put("pass","0");
            taskService.complete(task.getId(),map);
        }

    }

    private void startProcess(CapPreApproval capPreApproval,String procInsId, Map<String, Object> map) {

        try {

            //返回修改材料
            if(StringUtils.isNotEmpty(procInsId)){
                capPreApproval.setApprovalStatus(ApprovalFlowEnum.getNowNodeStatus("材料预审中").getStatus());
                Task task =taskService.createTaskQuery().processInstanceId(procInsId).singleResult();
                if(task!=null){
                    taskService.addComment(task.getId(),procInsId,"start[调整后提交]");
                    map.put("pass",2);
                    taskService.complete(task.getId(),map);
                }

            }else{//第一次提交
                CapService capService = capServiceService.selectByPrimaryKey(capPreApproval.getServiceId());
                capPreApproval.setApprovalDept(capService.getSysOfficeId());
                capPreApproval.setApprovalStatus(ApprovalFlowEnum.getNowNodeStatus("材料预审中").getStatus());
                capPreApproval.setTaskStatus(ApprovalConstant.TASKSTATUS[0]);
                capPreApproval.setSubmitDate(new Date());
                map.put("taskName","流程启动");
                map.put("busTable",ApprovalConstant.APPROVAL_FLOW_TABLE);
                map.put("busId",capPreApproval.getId());
                ProcessInstance processInstance =runtimeService.startProcessInstanceByKey(ApprovalConstant.APPROVAL_FLOW_NAME,map);
                capPreApproval.setProcInsId(processInstance.getId());
                Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
                taskService.addComment(task.getId(),processInstance.getId(),"start[流程开始]");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
